<template>
  <drag-dialog v-model="visible" title="事件编辑">
    <div class="event-edit">
      <div class="edit-header">
        <div class="header-item">
          <div class="header-label">事件名:</div>
          <el-select v-model="curEventName" :disabled="isEventEdit()" @change="handleTypeChange" style="width: 150px">
            <el-option v-for="opt in curEvents" :key="opt.value" :label="opt.label" :value="opt.value" :disabled="isEventExist(opt.value)" />
          </el-select>
        </div>
        <div class="header-item">
          <div class="header-label">事件方法:</div>
          <div>{{ curEventName ? curEventName : '未选择' }}</div>
        </div>
      </div>
      <div class="edit-type">
        <el-radio-group v-model="curEventType" @change="handleModeChange">
          <el-radio-button label="调用模式" value="call" />
          <el-radio-button label="代码模式" value="code" />
        </el-radio-group>
      </div>
      <div class="edit-content">
        <template v-if="curEventType == 'code'">
          <div class="editor">
            <code-editor v-if="curEventType == 'code'" :languageSelector="false" :themeSelector="false" v-model="code" height="500px" :editorOption="editorOptions" />
          </div>
          <div class="desc">
            <el-form v-if="curEventObj" label-position="top" label-suffix=":">
              <el-form-item label="方法说明">
                <span>{{ curEventObj.desc }}</span>
              </el-form-item>
              <el-form-item label="入参">
                <span>{{ curEventObj.paramIn }}</span>
              </el-form-item>
              <el-form-item label="出参">
                <span>{{ curEventObj.paramOut }}</span>
              </el-form-item>
              <el-form-item label="平台内置对象">
                <span>{{ globalVars }}</span>
              </el-form-item>
            </el-form>
          </div>
        </template>
        <template v-else>
          <el-form label-position="right" label-suffix=":" label-width="100px" style="width: 100%">
            <custom-event-call v-model="event" :options="options" />
          </el-form>
        </template>
      </div>
    </div>
    <template #footer>
      <dialog-footer @ok="submit" @cancel="cancel" />
    </template>
  </drag-dialog>
</template>

<script>
import CodeEditor from '@/components/CodeEditor/src/CodeEditor.vue';
import customEventCall from './customEventCall.vue';

export default {
  name: 'CustomEventSetting',
  components: { CodeEditor, customEventCall },
  props: {
    modelValue: {
      type: Boolean,
      default: false
    },
    data: {
      type: Object,
      default: () => {}
    },
    options: {
      type: Object,
      default: () => {}
    },
    eventName: {
      type: String,
      default: ''
    },
    eventType: {
      type: String,
      default: 'code'
    },
    curEvents: {
      type: Array,
      default: () => []
    }
  },
  data() {
    return {
      visible: false,
      localData: {},
      curEventObj: undefined,
      curEventName: '',
      curEventType: '',
      code: '',
      event: {},
      editorOptions: {
        minimap: {
          enabled: false
        }
      },
      globalVars: `通过this.useAnvilCodeStore获取全局状态管理对象;\n
                     store下方法：\n
                     获取当前表单对象方法getCurPageForm();\n
                     获取指定类型和id的组件实例方法getInstance(pageId: string, type: 'form' | 'component', uuid: string)`
    };
  },
  watch: {
    modelValue: {
      handler(newVal) {
        this.visible = newVal;
      },
      immediate: true
    },
    visible: {
      handler(newVal) {
        this.$emit('update:modelValue', newVal);
      }
    },
    data: {
      handler(val) {
        if (val && this.eventName && val[this.eventName] && this.eventType == 'code') {
          this.code = String(val[this.eventName]);
        } else if (val && this.eventName && val[`_${this.eventName}`] && this.eventType == 'call') {
          this.event = val[`_${this.eventName}`];
        }
      },
      deep: true,
      immediate: true
    },
    eventName: {
      handler(val) {
        if (val) {
          this.curEventName = val;
          this.handleTypeChange();
        }
      },
      immediate: true
    },
    eventType: {
      handler(val) {
        if (val) {
          this.curEventType = val;
          this.handleModeChange(val);
        }
      },
      immediate: true
    }
  },
  methods: {
    // 根据不同的参数补全代码模板
    initCode() {
      if(!this.curEventObj){
        this.code = '() => {\r\n\r\n}';
      }else{
        this.code = `(${this.curEventObj.paramIn !== '无' ? this.curEventObj.paramIn : ''}) => {\r\n\r\n}`;
      }
    },
    handleTypeChange() {
      this.curEventObj = this.curEvents.find((opt) => opt.value == this.curEventName);
      if (this.curEventObj && !this.code) {
        this.initCode();
      }
    },
    handleModeChange(v) {
      if (v == 'call') {
        if (!Object.keys(this.event).length) {
          this.event = {
            components: [],
            params: {
              contantParams: [],
              compParams: [],
              withFormData: false,
              hookBefore: ''
            }
          };
        }
      } else {
        if (!this.code) {
          this.initCode();
        }
      }
    },
    submit() {
      if (!this.curEventName) {
        this.msgError('请选择事件名！');
        return;
      }
      if (this.curEventType == 'code') {
        this.$emit('update-event', this.curEventName, this.curEventType, this.code);
      } else {
        this.$emit('update-event', this.curEventName, this.curEventType, this.event);
      }
      this.visible = false;
    },
    cancel() {
      this.visible = false;
    },
    // 判断当前组件是否已经配置过该事件
    isEventExist(v) {
      return !!this.data[v] || !!this.data['_' + v];
    },
    // 是否处于编辑状态，编辑态不可修改事件类型
    isEventEdit() {
      return !!this.eventName;
    }
  }
};
</script>

<style lang="scss" scoped>
.event-edit {
  display: flex;
  flex-direction: column;
  gap: 20px;

  .edit-header {
    display: flex;
    align-items: center;
    gap: 40px;

    .header-item {
      display: flex;
      align-items: center;
      gap: 4px;

      .header-label {
        width: 80px;
      }
    }
  }

  .edit-content {
    display: flex;
    width: 100%;
    gap: 40px;

    .editor {
      width: 50%;
    }

    .desc {
      flex: 1;
    }
  }
}
</style>
